package service

import (
	"context"
	"fmt"
	"fx_swift_ifcgate/api"
	"fx_swift_ifcgate/internal/model"
	"fx_swift_ifcgate/pkg/code"
	"fx_swift_ifcgate/pkg/global"
	"fx_swift_ifcgate/pkg/internalerrors"
	"fx_swift_ifcgate/pkg/logger"
	"fx_swift_ifcgate/pkg/utils"
	"github.com/gogf/gf/v2/container/gmap"
	"github.com/spf13/cast"
	"time"
)

// 首页
type IIndexSrv interface {
	// 钱包数据
	AccountToTp3004(ctx context.Context) ([]*api.AccountToTp3004InfoRes, error)
	// 收款趋势
	CollectTrends(ctx context.Context, req *api.CollectTrendsReq) ([]*api.CollectTrendsRes, error)
	// 公告
	GetPlacard(ctx context.Context) ([]*api.GetPlacardRes, error)
}
type indexSrv struct {
}

func NewIndexSrv() IIndexSrv {
	return &indexSrv{}
}

// 首页帐户数据
func (i *indexSrv) AccountToTp3004(ctx context.Context) ([]*api.AccountToTp3004InfoRes, error) {
	var (
		err           error
		merchantToken string
		rateObj       *model.IfcgateRate
		tp3004Result  *api.Tp3004Res
		//tp1002Res     *api.Tp1002Res
		list = make([]*api.AccountToTp3004InfoRes, 0)
	)
	merchantToken, err = GetMerchantToToken(ctx)
	if merchantToken == "" || err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, err.Error())
	}
	tp3004Result, err = PostTp3004(&api.Tp3004Req{}, merchantToken)
	if len(tp3004Result.Tp3004InfoList.Tp3004Info) > 0 {
		for _, valueObj := range tp3004Result.Tp3004InfoList.Tp3004Info {
			if valueObj.Balance != "0.00" && valueObj.Currency != "USD" {
				//tp1002Res, err = PostTp1002(&api.Tp1002Req{
				//	MerOrderNo:    utils.GenerateCode32(),
				//	SellCurrency:  valueObj.Currency,
				//	BuyCurrency:   "USD",
				//	LockDirection: "SELL",
				//	Amount:        valueObj.Balance,
				//}, merchantToken)
				//if tp1002Res != nil {
				//	list = append(list, &api.AccountToTp3004InfoRes{
				//		Balance:  valueObj.Balance,
				//		Currency: valueObj.Currency,
				//		USD:      tp1002Res.Body.BuyAmount,
				//	})
				//}
				if err = global.GFDB.Model("ifcgate_rate").Fields("rate").
					Scan(&rateObj, "currency=?", valueObj.Currency); err != nil {
					logger.SugarLogger.Error(err)
				}
				fBalance := fmt.Sprintf("%.4f", cast.ToFloat64(valueObj.Balance)/rateObj.Rate)
				list = append(list, &api.AccountToTp3004InfoRes{
					Balance:  valueObj.Balance,
					Currency: valueObj.Currency,
					USD:      fBalance,
				})

			} else {
				list = append(list, &api.AccountToTp3004InfoRes{
					Balance:  valueObj.Balance,
					Currency: valueObj.Currency,
					USD:      "",
				})
			}
		}
	}
	return list, err
}

// 收款趋势
func (i *indexSrv) CollectTrends(ctx context.Context, req *api.CollectTrendsReq) ([]*api.CollectTrendsRes, error) {
	type DbVo struct {
		Amount      float64 `json:"amount"`
		Nums        int     `json:"nums"`
		ApproveTime string  `json:"approve_time"`
	}
	type TempObj struct {
		Amount float64 `json:"amount"`
		Nums   int     `json:"nums"`
	}
	var (
		err        error
		dateList   = make([]string, 0)
		ST         time.Time
		ET         time.Time
		merchantNo string
		dbVoList   []DbVo
		result     []*api.CollectTrendsRes
	)

	merchantNo = ctx.Value("MerchantNo").(string)

	ST, err = time.Parse("2006-01-02", req.StartTime)
	if err != nil {
		logger.SugarLogger.Error("startT时间解析错误")
	}
	ET, err = time.Parse("2006-01-02", req.EndTime)
	if err != nil {
		logger.SugarLogger.Error("startT时间解析错误")
	}

	diff := ET.Sub(ST)
	startYear, startMonth, _ := ST.Date()
	endYear, endMonth, _ := ET.Date()
	//如果两个日期天数大于30，并且月份不同
	if diff.Hours()/24 >= 30 {
		if startYear != endYear || startMonth != endMonth {
			dateList = utils.GenerateMonthList(ST, ET)

			mod := global.GFDB.Model("ifcgate_trade_order_mapping_flow")
			mod.Fields("SUM(amount) amount,count(1) nums,date_format(approve_time, '%Y-%m') approve_time")
			if len(req.Currency) > 0 {
				mod.Where("currency=?", req.Currency)
			}
			if err = mod.Where("merchant_no=? and date_format(approve_time,'%Y-%m-%d') >=? "+
				"and date_format(approve_time,'%Y-%m-%d') <= ? and status='02'", merchantNo, req.StartTime, req.EndTime).
				Group("approve_time").
				Order("approve_time desc").Scan(&dbVoList); err != nil {
				return nil, internalerrors.New(code.ErrUnknown, err.Error())
			}
		} else {
			mod := global.GFDB.Model("ifcgate_trade_order_mapping_flow")
			mod.Fields("SUM(amount) amount,count(1) nums,date_format(approve_time, '%Y-%m-%d') approve_time")
			if len(req.Currency) > 0 {
				mod.Where("currency=?", req.Currency)
			}
			if err = mod.Where("merchant_no=? and date_format(approve_time,'%Y-%m-%d') >=? "+
				"and date_format(approve_time,'%Y-%m-%d') <= ? and status='02'", merchantNo, req.StartTime, req.EndTime).
				Group("approve_time").
				Order("approve_time desc").Scan(&dbVoList); err != nil {
				return nil, internalerrors.New(code.ErrUnknown, err.Error())
			}
			dateList = utils.GenerateDayList(ST, ET)
		}
	} else {
		mod := global.GFDB.Model("ifcgate_trade_order_mapping_flow")
		mod.Fields("SUM(amount) amount,count(1) nums,date_format(approve_time, '%Y-%m-%d') approve_time")
		if len(req.Currency) > 0 {
			mod.Where("currency=?", req.Currency)
		}
		if err = mod.Where("merchant_no=? and date_format(approve_time,'%Y-%m-%d') >=? "+
			"and date_format(approve_time,'%Y-%m-%d') <= ? and status='02'", merchantNo, req.StartTime, req.EndTime).
			Group("approve_time").
			Order("approve_time desc").Scan(&dbVoList); err != nil {
			return nil, internalerrors.New(code.ErrUnknown, err.Error())
		}
		dateList = utils.GenerateDayList(ST, ET)
	}

	if len(dbVoList) > 0 {
		maps := gmap.ListMap{}
		for _, value := range dbVoList {
			if !maps.Contains(value.ApproveTime) {
				maps.Set(value.ApproveTime, TempObj{
					Amount: value.Amount,
					Nums:   value.Nums,
				})
			} else {
				valueObj := maps.Get(value.ApproveTime).(TempObj)
				valueObj.Nums += value.Nums
				valueObj.Amount += value.Amount
				maps.Set(value.ApproveTime, valueObj)
			}
		}

		for _, dateStr := range dateList {
			if !maps.Contains(dateStr) {
				result = append(result, &api.CollectTrendsRes{
					Amount:      "0",
					Nums:        "0",
					ApproveTime: dateStr,
				})
			}
		}

		maps.Iterator(func(key interface{}, value interface{}) bool {
			result = append(result, &api.CollectTrendsRes{
				Amount:      cast.ToString(value.(TempObj).Amount),
				Nums:        cast.ToString(value.(TempObj).Nums),
				ApproveTime: key.(string),
			})
			return true
		})
	} else {
		for _, dateStr := range dateList {
			result = append(result, &api.CollectTrendsRes{
				Amount:      "0",
				Nums:        "0",
				ApproveTime: dateStr,
			})
		}
	}
	return result, err
}

func (p *indexSrv) GetPlacard(ctx context.Context) ([]*api.GetPlacardRes, error) {
	var (
		err  error
		list = make([]*api.GetPlacardRes, 0)
	)
	if err = global.GFDB.Ctx(ctx).Schema("boss").Model("fx_placard").Where("type='ifcgate' and flag='1'").
		Order("created_at desc").Limit(1).
		Scan(&list); err != nil {
		logger.SugarLogger.Error(err.Error())
		return nil, internalerrors.New(code.ErrUnknown, err.Error())
	}
	return list, err
}
